﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using ColemanDevelopment.Utilities.Parsers.Xml;

namespace ColemanSoftware.Delicious.Modules.Data
{
    /// <summary>
    /// Handles the Requests to all access and CRUD operations
    /// for Delicious bookmarks
    /// </summary>
    public class Requestor : IRequestor
    {

        public enum MethodTypes
        {
            POST,
            GET,
            UPDATE,
            DELETE
        }

        #region PRIVATE FIELDS

        private MethodTypes _requestMethod;
        private string USERNAME = Properties.Settings.Default.userName;
        private string PASSWORD = Properties.Settings.Default.password;
        private string API_URI = Properties.Settings.Default.topLevelUri;
        private WebScrapper _webScraper;

        #endregion

        #region PUBLIC PROPERTIES

        public string Header { get; set; }
        /// <summary>
        /// Gets or sets the URI that will be doing the CRUD operation.
        /// </summary>
        /// <value>
        /// The URI.
        /// </value>
        public string Uri { get; set; }
        /// <summary>
        /// Gets or sets the request method.
        /// </summary>
        /// <value>
        /// The request method.
        /// </value>
        public MethodTypes RequestMethod { get { return _requestMethod; } set { _requestMethod = value; } }


        #endregion

        #region CONSTRUCTOR(S)

        public Requestor()
        {
            _webScraper = new WebScrapper(USERNAME, PASSWORD);
        }

        public Requestor(string userName, string password)
        {
            _webScraper = new WebScrapper(userName, password);
        }

        public Requestor(UserAccount userAccount)
        {
            _webScraper = new WebScrapper(userAccount);
        }

        #endregion

        public string GetRecentBookmarks()
        {
            string results = _webScraper.RequestData(API_URI + @"/posts/dates?red=api");

            return results;
        }


        /// <summary>
        /// Adds the bookmark.
        /// </summary>
        /// <param name="title">The title.</param>
        /// <param name="description">The description.</param>
        /// <param name="url">The URL.</param>
        /// <param name="tags">The tags.</param>
        /// <param name="dateTime">The date time.</param>
        /// <returns></returns>
        public string AddBookmark(string title, string description, string url, List<Tag> tags)
        {
            StringBuilder tagBuilder = new StringBuilder();
            string errors = "";
            string parsedResults = "";
            DateTime createdDate = DateTime.UtcNow;
            errors = ErrorValidator.ValidateBookmarkData(title, description, url, createdDate);

            if (!String.IsNullOrEmpty(errors))
            {
                parsedResults = DeliciousResultsParser.ParseResultCode(errors);
                return parsedResults;
            }

            foreach (Tag tag in tags)
            {
                tagBuilder.Append(tag.Value);
            }

            string fullUrl = API_URI + @"/posts/add?url=" + url
                                                + "&description=" + description
                                                + "&tags" + tagBuilder
                                                + @"dt=" + DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ");

            string results = _webScraper.RequestData(fullUrl);
            parsedResults = DeliciousResultsParser.ParseResultCode(results);

            if (parsedResults == "done")
                return "Success";
            else
                return parsedResults;
        }

        /// <summary>
        /// Updates the bookmark.
        /// </summary>
        /// <param name="bookmarkName">Name of the bookmark.</param>
        /// <returns></returns>
        public string UpdateBookmark(string url, List<Tag> tags = null, string title = "", string description = "")
        {
            string errors = DeleteBookmark(url);

            if (!String.IsNullOrEmpty(errors))
                return errors;

            errors = AddBookmark(title, description, url, tags);

            return errors;
        }

        /// <summary>
        /// Deletes the bookmark.
        /// </summary>
        /// <param name="url">URL of the bookmark to delete.</param>
        /// <returns></returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public string DeleteBookmark(string url)
        {
            string results = ErrorValidator.ValidateString(() => url);

            if (results != null)
            {
                string fullUrl = API_URI + @"/posts/delete?url=" + url;

                results = _webScraper.RequestData(fullUrl);
            }
            else
                results = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><result code=\"Valid Url Required\"/>";

            return results;
        }

        public string GetBookmarkByDate(string startDate)
        {
            string fullUrl = "";
            string results = null;

            DateTime tempDate;
            string formattedDate = DateTime.TryParse(startDate, out tempDate) ? tempDate.ToString("yyyy-MM-ddTHH:mm:ssZ") : DateTime.MinValue.ToString();

            if (String.IsNullOrEmpty(formattedDate))
            {
                fullUrl = API_URI + @"/posts/get?dt=" + formattedDate;
                results = _webScraper.RequestData(fullUrl);
            }
            else
            {
                results = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><result code=\"Date is incorrect format.\"/>";
            }
            return results;
        }

        public string GetBookmarkByUri(Uri url)
        {
            string fullUrl = "";
            string results = "";

            var validated = ErrorValidator.ValidateObject(() => url);

            if (validated != null)
            {
                fullUrl = API_URI + @"/posts/get?url=" + url;
                results = _webScraper.RequestData(fullUrl);
            }
            else
                results = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><result code=\"Url must be provided.\"/>";

            return results;
        }

        public string GetBookmarkByTag(string filterTag)
        {
            string fullUrl = "";
            string results = null;

            fullUrl = API_URI + @"/posts/get?tag=" + filterTag;
            results = _webScraper.RequestData(fullUrl);

            return results;
        }


        #region PRIVATE METHODS

        ///// <summary>
        ///// Parses the results provided by Delicious API system
        ///// the results will be provided in XML format.
        ///// </summary>
        ///// <param name="results">The results.</param>
        ///// <returns></returns>
        //private static List<XmlData> ParseResults(string results)
        //{
        //    List<XmlData> data = new List<XmlData>();

        //    if (results != null)
        //        data = XmlParser.ParseXml(results).ToList();

        //    return data;
        //}

        //private static string ParseError(List<XmlData> dataToGetErrors)
        //{
        //    string error = "";

        //    // Make sure we have data
        //    if (dataToGetErrors != null && dataToGetErrors.Count != 0)
        //    {
        //        var resultXml = dataToGetErrors.Where(xml => xml.ElementName == "result");

        //        foreach (var d in resultXml)
        //        {
        //            AttributePair attr = d.Attributes.SingleOrDefault(x => x.Name == "code");
        //            // Were there errors?
        //            if (attr != null)
        //                error = attr.Value;
        //        }
        //    }

        //    return error;
        //}


        #endregion
    }
}
